import Vapor

struct SimpleBuildingController: RouteCollection {

  func boot(routes: RoutesBuilder) throws {
    let routes = routes.grouped("api", "simplebuildings")
    routes.get(use: getAllHandler)
    routes.post(use: createHandler)
    routes.get(":simplebuildingID", use: getHandler)
    routes.put(use: updateHandler)
    routes.delete(":simplebuildingID", use: deleteHandler)
//    routes.get("search", use: searchHandler)
    routes.get("first", use: getFirstHandler)
    routes.get("sorted", use: sortedHandler)
    routes.get(":simplebuildingID", "project", use: getProjectHandler)
  }

    func getAllHandler(_ req: Request) throws -> EventLoopFuture<[SimpleBuilding]> {
        SimpleBuilding.query(on: req.db).all()
    }
    
    func createHandler(_ req: Request) throws -> EventLoopFuture<SimpleBuilding> {
      let data = try req.content.decode(SimpleBuildingData.self)
        let simpleBuilding = SimpleBuilding(id: data.id, name: data.name ?? "", height: data.height, length: data.length, pitch: data.pitch, positionX: data.positionX, positionY: data.positionY, showFlag: data.showFlag, showTextBalloon: data.showTextBalloon, width: data.width, projectID: data.projectID ?? UUID())
      return simpleBuilding.save(on: req.db).map { simpleBuilding }
    }

    func getHandler(_ req: Request) throws -> EventLoopFuture<SimpleBuilding> {
        SimpleBuilding.find(req.parameters.get("simplebuildingID"), on: req.db)
      .unwrap(or: Abort(.notFound))
    }

    func updateHandler(_ req: Request) throws -> EventLoopFuture<SimpleBuilding> {
      let updateData = try req.content.decode(SimpleBuildingData.self)
        return SimpleBuilding.find(updateData.id, on: req.db)
        .unwrap(or: Abort(.notFound)).flatMap { simpleBuilding in
            simpleBuilding.id = updateData.id
            simpleBuilding.name = updateData.name
            simpleBuilding.height = updateData.height
            simpleBuilding.length = updateData.length
            simpleBuilding.positionX = updateData.positionX
            simpleBuilding.positionY = updateData.positionY
            simpleBuilding.showFlag = updateData.showFlag
            simpleBuilding.showTextBalloon = updateData.showTextBalloon
            simpleBuilding.width = updateData.width
            simpleBuilding.$project.id = updateData.projectID ?? UUID()


          return simpleBuilding.save(on: req.db).map {
            simpleBuilding
          }
      }
    }

    func deleteHandler(_ req: Request)
      throws -> EventLoopFuture<HTTPStatus> {
        SimpleBuilding.find(req.parameters.get("simplebuildingID"), on: req.db)
        .unwrap(or: Abort(.notFound))
        .flatMap { acronym in
          acronym.delete(on: req.db)
            .transform(to: .noContent)
      }
    }

//    func searchHandler(_ req: Request) throws -> EventLoopFuture<[SimpleBuilding]> {
//      guard let searchTerm = req
//        .query[String.self, at: "term"] else {
//        throw Abort(.badRequest)
//      }
//        return SimpleBuilding.query(on: req.db).group(.or) { or in
//            or.filter(\.$name == searchTerm)
//            or.filter(\.$name == searchTerm)
//
//
//        }.all()
//    }

    func getFirstHandler(_ req: Request) throws -> EventLoopFuture<SimpleBuilding> {
      return SimpleBuilding.query(on: req.db)
        .first()
        .unwrap(or: Abort(.notFound))
    }

    func sortedHandler(_ req: Request) throws -> EventLoopFuture<[SimpleBuilding]> {
      return SimpleBuilding.query(on: req.db).sort(\.$name, .ascending).all()
    }
    
    func getProjectHandler(_ req: Request) throws -> EventLoopFuture<Project> {
        SimpleBuilding.find(req.parameters.get("simplebuildingID"), on: req.db)
      .unwrap(or: Abort(.notFound))
      .flatMap { simpleBuilding in
        simpleBuilding.$project.get(on: req.db)
      }
    }
}

struct SimpleBuildingData: Content {
    var id: UUID?
    var name: String?
    var height: Double
    var length: Double
    var pitch: Double
    var positionX: Double
    var positionY: Double
    var showFlag: Bool
    var showTextBalloon: Bool
    var width: Double
    var projectID: UUID?
}
